package com.itlong.cloud.commons.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.itlong.cloud.POJO.DTO.app.AppElevatorAuthDTO;
import com.itlong.cloud.POJO.DTO.property.*;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.app.AppElevatorAuthVO;
import com.itlong.cloud.POJO.VO.app.AppElevatorInfoVO;
import com.itlong.cloud.POJO.VO.operate.OperateUpdateDetailVO;
import com.itlong.cloud.POJO.VO.property.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.app.dao.IAppDeviceDao;
import com.itlong.cloud.app.dao.IAppDevicePassRecordDao;
import com.itlong.cloud.commons.dao.ICloudElevatorDao;
import com.itlong.cloud.commons.dao.IPushCloudElevatorChangeLogDao;
import com.itlong.cloud.commons.service.ICloudElevatorService;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.operate.dao.IOperatePackageDao;
import com.itlong.cloud.property.dao.ICloudIntercomDeviceServiceDao;
import com.itlong.cloud.property.dao.IDeviceCloudControllerDao;
import com.itlong.cloud.property.dao.IDeviceEntranceInfoDao;
import com.itlong.cloud.property.dao.IPropertyEquipDao;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.string.StringUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import sun.rmi.runtime.Log;

import javax.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <desc>
 *      云电梯业务接口实现类
 * </desc>
 *
 * @createDate 2018/03/28
 */
@Service
@RefreshScope
public class CloudElevatorServiceImpl implements ICloudElevatorService{
    private static final Logger LOG = LoggerFactory.getLogger(CloudElevatorServiceImpl.class);
    @Value("${" + PlatformConstants.CLOUD_ELEVATOR_TOKEN_KEY + "}")
    String cloudElevatorTokenKey;

    @Autowired
    ICloudElevatorDao iCloudElevatorDao;

    @Autowired
    IAppDevicePassRecordDao iAppDevicePassRecordDao;

    @Autowired
    ICloudIntercomDeviceServiceDao iCloudIntercomDeviceServiceDao;

    @Autowired
    IAppDeviceDao iAppDeviceDao;

    @Autowired
    RedisService redisService;

    @Autowired
    MessageSender messageSender;

    @Autowired
    IOperatePackageDao iOperatePackageDao;

    @Autowired
    IDeviceCloudControllerDao iDeviceCloudControllerDao;
    private ExecutorService cachedThreadPool ;

    @Autowired
    IDeviceEntranceInfoDao iDeviceEntranceInfoDao;

    @PostConstruct
    public void init() {
        cachedThreadPool = Executors.newFixedThreadPool(100);
    }

    @Autowired
    IPropertyEquipDao iPropertyEquipDao;

    @Autowired
    IPushCloudElevatorChangeLogDao iPushCloudElevatorChangeLogDao;


    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;


    /**
     * <desc>
     *      获取设备状态
     * </desc>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2018/03/28
     */
    @Override
    public Integer getDeviceStatus(String sn) {
        try {
            return iCloudElevatorDao.getDeviceStatus(sn);
        }catch (Exception e){
            return null;
        }
    }

    /**
     * <desc>
     *      云电梯登录
     * </desc>
     *
     * @param sn
     * @param encryptionAbility 加密类型 0—设备不支持加密传输、1—设备支持自有加密方案、2—设备支持HTTPS安全传输、3—设备同时支持自有加密方案和HTTPS安全传输。
     * @return
     * @author Jiaqi.X
     * @createDate 2018/03/28
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public CloudElevatorVO login(String sn, String encryptionAbility) throws Exception {
        CloudElevatorVO elevator = iCloudElevatorDao.getDeviceInfoBySn(sn);
        if(elevator!=null) {
            //设置token
            elevator.setToken(UserTokenUtil.tokenEncrypt(sn,cloudElevatorTokenKey, SystemTypeEnum.CLOUD_ELEVATOR_SERVER.getType()));
            //设置过期时间
            elevator.setInvalidTime(DateUtil.fomatDate(
                    DateUtils.addSeconds(new Date(), RedisConstant.CLOUD_ELEVATOR_LOGIN_TIME.intValue()),
                    "yyyy-MM-dd HH:mm:ss"
            ));
            elevator.setEncryptMethod(StringUtils.isNotBlank(encryptionAbility) ? Integer.valueOf(encryptionAbility) : 0);
            List<CloudIntercomDeviceVO.PropertyValue> list = iCloudIntercomDeviceServiceDao.getPropertyInfo(elevator.getProjectId(),2);
            if (list.size() == 0) {
                list = new ArrayList<>();
                list.add(new CloudIntercomDeviceVO.PropertyValue());
            }
            elevator.setDeploys(list);
            //token入库
            iCloudElevatorDao.updateTokenBySn(elevator.getToken(),sn);
            //向阿里云iot中心注册设备 注册成功后更新设备信息
            if (elevator.getIotDeviceId() == null) {
                Map<String, Object> params = new HashMap<>();
                params.put("deviceOperateIotType", DeviceIotEnum.REGIST_DEVICE.getCommandType());
                params.put("productKey", elevator.getIotProductKey());
                params.put("deviceUnique",elevator.getDeviceUnique());
                Map<String,Object> result=new HashMap<>();
                result.put("data",params);
                messageSender.send(RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_QUEUE, JsonUtil.toJSON(result),
                        RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_EXCHANGE,RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_KEY);
            }
            //设置缓存
            redisService.set(RedisConstant.CLOUD_ELEVATOR_LOGIN_REDIS_KEY + elevator.getSn(),
                    RedisConstant.CLOUD_ELEVATOR_LOGIN_TIME, elevator);
            //清空过期的轮询命令
            iCloudElevatorDao.clearExpiredChangeLog(StringHandlerUtil.getProjectIdBySn(sn) + "1" +  StringHandlerUtil.getDeviceIdBySn(sn));
            return elevator;
        }else {
            return null;
        }
    }

    /**
     * <desc>
     *      通过token获取用户信息
     * </desc>
     *
     * @param token
     * @return
     * @author Jiaqi.X
     * @createDate 2018/03/29
     */
    @Override
    public CloudElevatorVO retrieve(String token) {
        try {
            if (StringUtils.isBlank(token)) {
                return null;
            }
            //解密token获取设备sn
            String sn = UserTokenUtil.tokenDecrypt(token, cloudElevatorTokenKey);
            if (StringUtils.isBlank(sn)) {
                return null;
            }
            CloudElevatorVO elevator = (CloudElevatorVO) redisService.getObject(RedisConstant.CLOUD_ELEVATOR_LOGIN_REDIS_KEY + sn, CloudElevatorVO.class);
            if (elevator == null) {
                elevator = iCloudElevatorDao.getDeviceInfoBySn(sn);
                if (StringUtils.isBlank(elevator.getToken()) || !token.equals(elevator.getToken())) {
                    return null;
                }
                //重新设置缓存
                elevator.setToken(token);
                elevator.setInvalidTime(DateUtil.fomatDate(
                        DateUtils.addSeconds(new Date(), RedisConstant.CLOUD_ELEVATOR_LOGIN_TIME.intValue()),
                        "yyyy-MM-dd HH:mm:ss"
                ));
                redisService.set(RedisConstant.CLOUD_ELEVATOR_LOGIN_REDIS_KEY + elevator.getSn(),
                        RedisConstant.CLOUD_ELEVATOR_LOGIN_TIME, elevator);
            }
            return elevator;
        }catch (Exception e){
            return null;
        }
    }

    /**
     * <desc>
     *      更新云电梯缓存iot信息
     * </desc>
     *
     * @param cloudElevatorVO
     * @return
     * @author Jiaqi.X
     * @createDate 2018/03/29
     */
    @Override
    public CloudElevatorVO updateCloudElevatorIotCacheInfo(CloudElevatorVO cloudElevatorVO) {
        CloudElevatorVO dbVo = iCloudElevatorDao.getDeviceInfoBySn(cloudElevatorVO.getSn());
        cloudElevatorVO.setIotDeviceId(dbVo.getIotDeviceId());
        cloudElevatorVO.setIotDeviceSecret(dbVo.getIotDeviceSecret());
        cloudElevatorVO.setIotDeviceStatus(dbVo.getIotDeviceStatus());
        cloudElevatorVO.setIotDeviceWorkStatus(dbVo.getIotDeviceWorkStatus());
        List<CloudIntercomDeviceVO.PropertyValue> list = iCloudIntercomDeviceServiceDao.getPropertyInfo(dbVo.getProjectId(),2);
        if (list.size() == 0) {
            list = new ArrayList<>();
            list.add(new CloudIntercomDeviceVO.PropertyValue());
        }
        cloudElevatorVO.setDeploys(list);
        cloudElevatorVO.setChargeMode(dbVo.getChargeMode());
        cloudElevatorVO.setEquipMode(dbVo.getEquipMode());
        cloudElevatorVO.setIotPlatform(dbVo.getIotPlatform());
        cloudElevatorVO.setIotDevicePassword(dbVo.getIotDevicePassword());
        if(StringUtils.isNotBlank(cloudElevatorVO.getIotDeviceId())){
            //如果iot信息不为空，则更新缓存
            cloudElevatorVO.setInvalidTime(DateUtil.fomatDate(
                    DateUtils.addSeconds(new Date(), RedisConstant.CLOUD_ELEVATOR_LOGIN_TIME.intValue()),
                    "yyyy-MM-dd HH:mm:ss"
            ));
            redisService.set(RedisConstant.CLOUD_ELEVATOR_LOGIN_REDIS_KEY + cloudElevatorVO.getSn(),
                    RedisConstant.CLOUD_ELEVATOR_LOGIN_TIME, cloudElevatorVO);
        }
        return cloudElevatorVO;
    }

    /**
     * <desc>
     *      上报设备能力集
     * </desc>
     *
     * @param deviceUnique 设备唯一码
     * @param productKey 阿里云产品key
     * @param deviceProJs 设备属性
     * @author Jiaqi.X
     * @createDate 2018/03/29
     */
    @Override
    public void reportCapacitySet(String deviceUnique, String productKey, String deviceProJs) throws Exception {

        //保存设备属性
        CloudElevatorProJsDTO dto = JsonUtil.decode(deviceProJs, new TypeReference<CloudElevatorProJsDTO>() {
        });

        //此处处理电梯若绑定了摄像头且上报时包含摄像头的在线离线状态，则将状态更新至缓存中
        DeviceAiCameraInfoVO aiCameraInfoVO = iCloudElevatorDao.getAiCameraInfoByElevatorDeviceUnique(deviceUnique);
        if(aiCameraInfoVO!=null && StringUtils.isNotBlank(aiCameraInfoVO.getCameraId())){
            String isOnline = (StringUtils.isNotBlank(dto.getIsWebCamOnline())&&"1".equals(dto.getIsWebCamOnline()))?"1":"0";
            redisService.set(RedisConstant.DEVICE_AI_CAMERA_IS_ONLINE_KEY + aiCameraInfoVO.getCameraId(),isOnline);
        }

        if(StringUtils.isEmpty(dto.getDeviceAttributes())){
            //默认型号为ITL-YDT
            dto.setDeviceAttributes("3");
        }
        Map<String,Object>  proMap  =  new HashMap<String,Object>();
        int  screen  =  dto.getScreen() ? 1 : 0;
        proMap.put("deviceUnique",deviceUnique);
        proMap.put("version",dto.getVersion());
        proMap.put("screen",screen);
        proMap.put("deviceAttributes",dto.getDeviceAttributes());
        proMap.put("mac",dto.getMac());
        proMap.put("cmdList",dto.getCmdList());
        //查询产品型号代码
        String  productCode =   iCloudElevatorDao.getProductCode(dto.getDeviceAttributes());
        dto.setProductCode(productCode);
        proMap.put("productCode",dto.getProductCode());
        String status  =  iCloudElevatorDao.getElevatorDeviceExist(deviceUnique);
        if(StringUtils.isNotEmpty(status)){
            //更新设备主表
            iCloudElevatorDao.updatePro(proMap);
        }else{
            //更新特殊设备主表
            iCloudElevatorDao.updateSpecialPro(proMap);
        }
        //iot上报设备属性
        Map<String,Object> params = new HashMap<>();
        params.put("deviceUnique",deviceUnique);
        params.put("productKey",productKey);
        params.put("deviceOperateIotType", DeviceIotEnum.SAVE_DEVICE_PROP.getCommandType());
        params.put("deviceProJs", deviceProJs);
        Map<String,Object> result = new HashMap<>();
        result.put("data", params);
        //向阿里云iot发送消息保存设备属性
//        messageSender.send(RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_QUEUE, JsonUtil.toJSON(result),
//                RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_EXCHANGE,RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_KEY);
    }


    /**
     * <desc>
     *      获取固定密码
     * </desc>
     *
     * @param dto
     * @return
     * @author Jiaqi.X
     * @createDate 2018/03/30
     */
    @Override
    public CloudElevatorRoomPwdPageVO pullDevicePwd(CloudElevatorPageDTO dto) throws Exception {
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(dto);
        //分页类默认pageSize为20
        Page<CloudElevatorRoomPwdVO> page = new Page<>(dto.getPage().toString(),dto.getPageSize().toString());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        List<CloudElevatorRoomPwdVO> list = iCloudElevatorDao.getPullDevicePwdPage(params);
        for(CloudElevatorRoomPwdVO roomPwdVO : list){
            Integer count = iCloudElevatorDao.getUserIsFrost(dto.getSn().substring(0,8),roomPwdVO.getRoomId());
            if(count>0){
                roomPwdVO.setOpenPwd("");
            }
        }
        page.setRows(list, iCloudElevatorDao.getPullDevicePwdPageCount(params));
        CloudElevatorRoomPwdPageVO cloudElevatorRoomPwdPageVO=new CloudElevatorRoomPwdPageVO();
        cloudElevatorRoomPwdPageVO.setDevicePwdArr(page.getRows());
        cloudElevatorRoomPwdPageVO.setTotal(page.getPage().getTotalNumber());
        cloudElevatorRoomPwdPageVO.setCurrentTotal(page.getPage().getPageSize());
        cloudElevatorRoomPwdPageVO.setHaveNext(page.getPage().getTotalPage()-page.getPage().getCurrentPage() > 0 ? 1: 0);
        return cloudElevatorRoomPwdPageVO;
    }

    /**
     * <desc>
     *      获取轮询数据分页列表
     * </desc>
     *
     * @param dto
     * @return
     * @author Jiaqi.X
     * @createDate 2018/04/03
     */
    @Override
    public Page<CloudElevatorChangeLogPageVO> getChangeLogPage(CloudIntercomChangeLogGetDTO dto) throws Exception {
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(dto);
        String deviceUnique = "";
        if(dto.getDeviceType().equals(PropertyEquipTypeEnum.CLOUD_ELEVATOR_CLUSTER_CONTROLLER.getType().toString())){
            deviceUnique = StringHandlerUtil.getControllerDeviceUniqueBySn(dto.getSn());
        }else{
            deviceUnique = StringHandlerUtil.getElevatorDeviceUniqueBySn(dto.getSn());
        }
        params.put("deviceUnique",deviceUnique);
        //1.分页获取待处理命令
        Page<CloudElevatorChangeLogPageVO> page = new Page<>();
        page.getPage().setCurrentPage("1");
        page.getPage().setPageSize(dto.getPageSize().toString());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        List<CloudElevatorChangeLogPageVO> orderVOS =
                iCloudElevatorDao.getChangeLogPage(params);
        Integer count = iCloudElevatorDao.getChangeLogPageCount(deviceUnique);
        //填充返回数据集
        page.setRows(orderVOS, count);

        //2.对命令做后续处理
        if (null != orderVOS && !orderVOS.isEmpty()){
            //a.将commandData转换为JSONObject
            for (CloudElevatorChangeLogPageVO orderVO: orderVOS){
                //全量更新时，commandData不是json格式
                if (orderVO.getCommandData() != null &&
                        !PushElevatorChangeEnum.PUSH_FULL.getType().toString().equals(orderVO.getCommandType())){
                    orderVO.setCommandData(JSON.parse(orderVO.getCommandData().toString()));
                }
                if (orderVO.getCommandData() == null){
                    orderVO.setCommandData(new HashMap<>());
                }
            }
            //b.将命令标记为处理中
            String[] idArr = new String[orderVOS.size()];
            for (int i = 0; i< idArr.length; i++){
                idArr[i] = orderVOS.get(i).getId();
            }
            iCloudElevatorDao.changeChangeLogOrdersStatus(deviceUnique, idArr, 1);
        }
        return page;
    }


    /**
     * <desc>
     * 云电梯设备批量完成轮询命名
     * </desc>
     *
     * @param sn
     * @param ids 轮询命令，多个以英文逗号拼接
     * @return 受影响的行数
     * @throws Exception
     * @author wangzhi
     * @createDate 2018-04-03
     */
    @Override
    public Integer batchFinishChangeLogOrders(String sn, String ids,String deviceType) throws Exception {
        String[] idArr = StringHandlerUtil.splitString(ids);
        if(deviceType.equals(PropertyEquipTypeEnum.CLOUD_ELEVATOR_CLUSTER_CONTROLLER.getType().toString())){
            return iCloudElevatorDao.changeChangeLogOrdersStatus(StringHandlerUtil.getControllerDeviceUniqueBySn(sn),idArr,2);
        }else{
            return iCloudElevatorDao.changeChangeLogOrdersStatus(StringHandlerUtil.getElevatorDeviceUniqueBySn(sn),idArr,2);
        }
    }

    /**
     * <desc>
     *      校验动态开门密码
     * </desc>
     *
     * @param dto
     * @return
     * @author Jiaqi.X
     * @createDate 2018/04/11
     */
    @Override
    public Boolean checkDynamicPwd(CloudIntercomDynamicPwdCheckDTO dto) throws Exception {
        CloudElevatorVO elevator = this.retrieve(dto.getToken());
        Map<String,Object> buildAndUnit = iCloudElevatorDao.getBuildAndUnitBySn(dto.getSn());
        String buildId = buildAndUnit.get("buildId").toString();
        String[] unitIds = StringHandlerUtil.splitString(buildAndUnit.get("unitIds").toString());
        //校验动态密码
        AppVisitorPassCodeRecordPO passCode = iCloudElevatorDao.checkDynamicPwd(StringHandlerUtil.getProjectIdBySn(elevator.getSn()),
                dto.getDynamicPwd(),dto.getFloorNum(),buildId,unitIds);
        Boolean mark = false;
        //针对临时权限设备校验动态密码
        AppVisitorPassCodeRecordPO passCodeByTemAuth = null;
        if(passCode == null){
            passCodeByTemAuth = iCloudElevatorDao.checkDynamicPwdForTemporartAuth(StringHandlerUtil.getProjectIdBySn(elevator.getSn()),
                    dto.getDynamicPwd(),buildId);
            if(passCodeByTemAuth != null && (StringUtils.isNotEmpty(passCodeByTemAuth.getBackDoorElevatorAuth()) || StringUtils.isNotEmpty(passCodeByTemAuth.getMainDoorElevatorAuth()))){
                String deviceId = dto.getSn().substring(dto.getSn().length()-4,dto.getSn().length());
                if(StringUtils.isNotEmpty(passCodeByTemAuth.getBackDoorElevatorAuth())){
                    Map<String,Object> backDoorElevatorAuth = JsonUtil.JsonToMap(passCodeByTemAuth.getBackDoorElevatorAuth());
                    if(backDoorElevatorAuth.containsKey(deviceId)){
                        String backFloor = backDoorElevatorAuth.get(deviceId).toString();
                        if(backFloor.contains(","+dto.getFloorNum()) || backFloor.contains(","+dto.getFloorNum()+",") || backFloor.contains(dto.getFloorNum()+",")
                                || (!backFloor.contains(",") && backFloor.equals(dto.getFloorNum()))){
                            for(String unit : unitIds){
                                if(passCodeByTemAuth.getUnitId().contains(unit)){
                                    mark = true;
                                    break;
                                }
                            }
                        }
                    }
                }
                if(!mark && StringUtils.isNotEmpty(passCodeByTemAuth.getMainDoorElevatorAuth())){
                    Map<String,Object> mainDoorElevatorAuth = JsonUtil.JsonToMap(passCodeByTemAuth.getMainDoorElevatorAuth());
                    if(mainDoorElevatorAuth.containsKey(deviceId)){
                        String mainFloor = mainDoorElevatorAuth.get(deviceId).toString();
                        if(mainFloor.contains(","+dto.getFloorNum()) || mainFloor.contains(","+dto.getFloorNum()+",") || mainFloor.contains(dto.getFloorNum()+",")
                                || (!mainFloor.contains(",") && mainFloor.equals(dto.getFloorNum()))){
                            for(String unit : unitIds){
                                if(passCodeByTemAuth.getUnitId().contains(unit)){
                                    mark = true;
                                    break;
                                }
                            }
                        }
                    }
                }

            }
        }
        if(passCode == null && !mark){
            return false;
        }
        if(passCode == null){
            passCode = passCodeByTemAuth;
        }
        boolean pushBlackList = false;
        //3.增加动态密码已使用次数
        if(iPropertyEquipDao.checkEquipMode(elevator.getDeviceUnique(),1) > 0) {
            QrcodePassUserInfoVO vo = iPropertyEquipDao.findRoomQrcodeInfoByPassId(passCode.getPassId());
            if (vo != null) {
                //更新访客使用次数
                if (vo.getChargeMode() != null && vo.getChargeMode() == 2
                        && vo.getRoomChargeMode() != null && vo.getRoomChargeMode() == 1 && vo.getUsableCount() <= 0) {
                    return false;
                }
                iPropertyEquipDao.udpateAppVisitorUseNum(vo.getUserId());
                //更新业主房间次数
                if (vo.getChargeMode() != null && vo.getChargeMode() == 2
                        && vo.getRoomChargeMode() != null && vo.getRoomChargeMode() == 1) {
                    if (StringUtils.isNotBlank(vo.getQrcodeBatchRecordId())) {
                        Integer row = iPropertyEquipDao.updateQrcodeRoomCount(vo.getQrcodeBatchRecordId(), vo.getUsableCount() > 1 ? 1 : 0);
                        if (row < 1 || vo.getUsableCount() == 1) {
                            //推送黑名单数据
                            pushBlackList = true;
                        }
                    }
                }
            }
        }
        //2.生成动态密码通行记录
        TimeTaskDevicePassRecordPO po=new TimeTaskDevicePassRecordPO();
        po.setPdId(LogicIdUtil.bussinessId());
        po.setProjectId(StringHandlerUtil.getProjectIdBySn(dto.getSn()));
        po.setDeviceType(PropertyEquipTypeEnum.CLOUD_PASS_RECORD_ELEVATOR.getType());
        po.setDeviceUnique(elevator.getDeviceUnique());
        po.setDeviceName(elevator.getDeviceName());
        po.setOpenType(OpenTypeEnum.BY_DYNAMIC_PASSWORD.getType());
        po.setRoomNum(iCloudElevatorDao.getRoomNumByRoomId(passCode != null?passCode.getRoomId():passCodeByTemAuth.getRoomId()));
        po.setPassTime(new Date());
        po.setUploadTime(new Date());
        po.setIsOpen(0);
        po.setSynchro(0);
        po.setSource(4);
        po.setDynamicPassword(dto.getDynamicPwd());
        po.setStatus(DataStatusEnum.NORMAL.getType());
        po.setCreateTime(new Date());
        iAppDevicePassRecordDao.save(SqlUtil.durableData(po,PlatformConstants.TABLE_SAVE));
        if(pushBlackList){
            String projectId = StringHandlerUtil.getProjectIdBySn(dto.getSn());
            //推送数据
            //推送黑名单更新数据
            List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
            List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
            List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
            Map<String,Object> blackList = new HashMap<>();
            blackList.put("projectId", projectId);
            blackList.put("roomId", passCode.getRoomId());
            blackList.put("version",0);
            DeviceBusinessChangeLogPO talkPO = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_BLACK_LIST, JsonUtil.toJSON(blackList), projectId);
            changes.add(talkPO);
            DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId, CloudElevatorChangeBusinessEnum.PUSH_BLACK_LIST, JsonUtil.toJSON(blackList));
            elevatorChanges.add(elevatorPo);
            DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId, CloudEntranceChangeBusinessEnum.PUSH_BLACK_LIST, JsonUtil.toJSON(blackList));
            entranceChanges.add(entrancePO);
            JSONObject pushJs = new JSONObject();
            pushJs.put("data", changes);
            //发送云对讲业务指令
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE, JsonUtil.toJSON(pushJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE, RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
            pushJs.put("data", elevatorChanges);
            //推送云电梯业务指令
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(pushJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
            //发送云门禁业务指令
            pushJs.put("data", entranceChanges);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(pushJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
            );
        }
        return true;
    }

    /**
     * <desc>
     *      生成刷卡通行记录
     * </desc>
     *
     * @param token
     * @return 记录id
     * @author Jiaqi.X
     * @createDate 2018/04/28
     */
    @Override
    public String saveCardPassRecord(String token) throws Exception {
        CloudElevatorVO elevator = this.retrieve(token);
        //生成动态密码通行记录
        TimeTaskDevicePassRecordPO po=new TimeTaskDevicePassRecordPO();
        po.setPdId(LogicIdUtil.bussinessId());
        po.setProjectId(StringHandlerUtil.getProjectIdBySn(elevator.getSn()));
        po.setDeviceType(PropertyEquipTypeEnum.CLOUD_PASS_RECORD_ELEVATOR.getType());
        po.setDeviceUnique(elevator.getDeviceUnique());
        po.setDeviceName(elevator.getDeviceName());
        po.setOpenType(OpenTypeEnum.BY_CARD.getType());
        po.setPassTime(new Date());
        po.setUploadTime(new Date());
        po.setIsOpen(0);
        po.setSynchro(0);
        po.setSource(4);
        po.setStatus(DataStatusEnum.NORMAL.getType());
        po.setCreateTime(new Date());
        iAppDevicePassRecordDao.save(SqlUtil.durableData(po,PlatformConstants.TABLE_SAVE));
        return po.getPdId();
    }

    /**
     * <desc>
     *      获取云电梯设备更新信息
     * </desc>
     *
     * @param sn
     * @param filePackage 安装文件 包名
     * @param versionCode 安装文件 版本号
     * @param deviceType 软件类型 0安卓APK程序，1安卓系统固件，2按键单片机固件
     * @return
     * @author Qiang.S
     * @createDate 2018/08/30
     */
    @Override
    public CloudDeviceUpdateInfoVO deviceElevatorUpdate(String sn, String filePackage, String versionCode, String deviceType) throws Exception {
        //根据sn,查询指令
        List<CloudIntercomChangeLogOrderVO> list = iCloudElevatorDao.getUpdateDeviceInfo(StringHandlerUtil.getElevatorDeviceUniqueBySn(sn));
        if (list.size() == 0) {//无此设备升级命令
            return null;
        }
        StringBuffer ids = new StringBuffer();
        //取消所有沉余指令
        for (int i=1;i<list.size();i++) {
            ids.append(list.get(i).getId().toString()+",");
        }
        String[] id = ids.toString().split(",");

        OperateUpdateDetailVO operateUpdateDetailVO = iOperatePackageDao.getUpdateDetailForDeviceUpdate(list.get(0).getCommandData().toString(),filePackage,deviceType,"0");
        if (operateUpdateDetailVO == null) {
            return null;
        }
        CloudDeviceUpdateInfoVO cloudDeviceUpdateInfoVO = new CloudDeviceUpdateInfoVO();
        cloudDeviceUpdateInfoVO.setCommandId(list.get(0).getId().toString());
        cloudDeviceUpdateInfoVO.setFileName(operateUpdateDetailVO.getUpdateName());
        cloudDeviceUpdateInfoVO.setMd5(operateUpdateDetailVO.getMd5());
        cloudDeviceUpdateInfoVO.setVersionCode(operateUpdateDetailVO.getVersion());
        cloudDeviceUpdateInfoVO.setUrl(operateUpdateDetailVO.getUpdateUrl());

        //将所有沉余指令清除
        iCloudElevatorDao.changeChangeLogOrdersStatus(StringHandlerUtil.getElevatorDeviceUniqueBySn(sn),id,2);
        //将执行的指令调整为 处理中
        String[] newId = {list.get(0).getId().toString()};
        iCloudElevatorDao.changeChangeLogOrdersStatus(StringHandlerUtil.getElevatorDeviceUniqueBySn(sn), newId, 1);
        return cloudDeviceUpdateInfoVO;
    }

    /**
     * <desc>
     *      获取云群控器设备更新信息
     * </desc>
     *
     * @param sn
     * @param filePackage 安装文件 包名
     * @param versionCode 安装文件 版本号
     * @param deviceType 软件类型 0安卓APK程序，1安卓系统固件，2按键单片机固件
     * @return
     * @author Qiang.S
     * @createDate 2018/08/30
     */
    @Override
    public CloudDeviceUpdateInfoVO deviceClusterUpdate(String sn, String filePackage, String versionCode, String deviceType) throws Exception {
        //根据sn,查询指令
        List<CloudIntercomChangeLogOrderVO> list = iCloudElevatorDao.getUpdateDeviceInfo(StringHandlerUtil.getControllerDeviceUniqueBySn(sn));
        if (list.size() == 0) {//无此设备升级命令
            return null;
        }
        StringBuffer ids = new StringBuffer();
        //取消所有沉余指令
        for (int i=1;i<list.size();i++) {
            ids.append(list.get(i).getId().toString()+",");
        }
        String[] id = ids.toString().split(",");

        OperateUpdateDetailVO operateUpdateDetailVO = iOperatePackageDao.getUpdateDetailForDeviceUpdate(list.get(0).getCommandData().toString(),filePackage,deviceType,"3");
        if (operateUpdateDetailVO == null) {
            return null;
        }
        CloudDeviceUpdateInfoVO cloudDeviceUpdateInfoVO = new CloudDeviceUpdateInfoVO();
        cloudDeviceUpdateInfoVO.setCommandId(list.get(0).getId().toString());
        cloudDeviceUpdateInfoVO.setFileName(operateUpdateDetailVO.getUpdateName());
        cloudDeviceUpdateInfoVO.setMd5(operateUpdateDetailVO.getMd5());
        cloudDeviceUpdateInfoVO.setVersionCode(operateUpdateDetailVO.getVersion());
        cloudDeviceUpdateInfoVO.setUrl(operateUpdateDetailVO.getUpdateUrl());

        //将所有沉余指令清除
        iCloudElevatorDao.changeChangeLogOrdersStatus(StringHandlerUtil.getControllerDeviceUniqueBySn(sn),id,2);
        //将执行的指令调整为 处理中
        String[] newId = {list.get(0).getId().toString()};
        iCloudElevatorDao.changeChangeLogOrdersStatus(StringHandlerUtil.getControllerDeviceUniqueBySn(sn),newId,1);
        return cloudDeviceUpdateInfoVO;
    }

    /**
     * <desc>
     *      获取云设备的楼层映射信息
     * </desc>
     *
     * @param sn
     * @param deviceType
     * @return
     * @author Jiaqi.X
     * @createDate 2018/11/22
     */
    @Override
    public CloudDeviceFloorInfoVO getCloudDeviceFloorInfo(String sn,String deviceType) {
        Map<String,Object> minAndMaxFloor;
        //获取电梯起始楼层及结束楼层
        if (deviceType != null && "128".equals(deviceType)) {//群控器
            minAndMaxFloor = iAppDeviceDao.getMinAndMaxFloorForController(StringHandlerUtil.getControllerDeviceUniqueBySn(sn));
            sn = iDeviceCloudControllerDao.getControllerBindElevatorDeviceSn(StringHandlerUtil.getControllerDeviceUniqueBySn(sn));
        }else {
            minAndMaxFloor = iAppDeviceDao.getMinAndMaxFloor(StringHandlerUtil.getElevatorDeviceUniqueBySn(sn));
        }
        //获取电梯副盘使用状态
        Integer bracketPanel = iPushCloudElevatorChangeLogDao.getBracketPanelBySn(sn);
        Integer startFloor = minAndMaxFloor==null || minAndMaxFloor.get("minFloor") == null ? null : Double.valueOf(minAndMaxFloor.get("minFloor").toString()).intValue();
        Integer endFloor = minAndMaxFloor==null || minAndMaxFloor.get("maxFloor") == null ? null : Double.valueOf(minAndMaxFloor.get("maxFloor").toString()).intValue();
        CloudDeviceFloorInfoVO vo = iCloudElevatorDao.getCloudDeviceFloorInfo(sn,startFloor,endFloor);
        //清空不用的字段内容
        if (bracketPanel == 0) {
            vo.setTerminalNumSlave1("");
            vo.setTerminalNumSlave2("");
        } else if (bracketPanel == 1) {
            vo.setTerminalNumSlave2("");
        }
        return vo;
    }

    /**
     * <desc>
     *       获取云电梯设备服务权限信息
     * </desc>
     *
     * @param getDTO
     * @return
     * @author Qiang.S
     * @createDate 2019/04/26
     */
    @Override
    public Page<CloudElevatorDeviceAuthVO.Room> getDeviceServeRoomsByPage(CloudIntercomDeviceAuthGetDTO getDTO) {
            String deviceUnique = StringHandlerUtil.getElevatorDeviceUniqueBySn(getDTO.getSn());
            Page<CloudElevatorDeviceAuthVO.Room> page = new Page<>();
            //1.分页获取云对讲服务的房间列表
            page.getPage().setCurrentPage(getDTO.getPage().toString());
            page.getPage().setPageSize(getDTO.getPageSize().toString());

            List<CloudElevatorDeviceAuthVO.Room> rooms =
                    iCloudElevatorDao.getServeRoomsPage(deviceUnique,
                            StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique),
                            page.getPage().getStartSlip(), page.getPage().getPageSize());

            Integer count = iCloudElevatorDao.getServeRoomsCount(deviceUnique,StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique)
            );
            //填充返回数据集
            page.setRows(rooms, count);
            return page;
    }

    /**
     * <desc>
     *      获取房间下的住户信息
     * <desc/>
     *
     * @param roomIds 房间id
     * @return
     * @author Qiang.S
     * @createDate 2019-04-26
     */
    @Override
    public List<CloudElevatorDeviceAuthVO.RoomUser> getUsersByRoomIds(String roomIds) {
        String[] idArr = StringHandlerUtil.splitString(roomIds);
        if (idArr.length == 0){
            return null;
        }
        return iCloudElevatorDao.getUsersByRoomIds(idArr);
    }

    /**
     * <desc>
     *      根据设备编号获取访客信息
     * </desc>
     *
     * @param deviceUnique 设备唯一码
     * @return
     * @author Qiang.S
     * @createDate 2019/04/26
     */
    @Override
    public List<CloudIntercomVisitorVO> getVisitorInfoByUnique(String deviceUnique) {
        return iCloudElevatorDao.getVisitorInfoByUnique(deviceUnique);
    }

    /**
     * <desc>
     *     通知云端升级失败原因
     * </desc>
     *
     * @param sn
     * @param id 轮询命令
     * @param msg 失败原因
     * @return 受影响的行数
     * @throws Exception
     * @author Qiang.S
     * @createDate 2019-08-12
     */
    @Override
    public Integer reportUpdateResult(String sn, String id, String msg) throws Exception {
        return iCloudElevatorDao.reportUpdateResult(sn, id, 3, msg);
    }

    /**
     * <desc>
     *     根据房间ID查询对应的楼栋与单元ID
     * </desc>
     *
     * @param roomId
     * @return
     * @author Jiaqi.X
     * @createDate 2018/04/03
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public String deviceChangeLogGetBuildAndUnitIdByRoomId(String roomId){
        return iCloudElevatorDao.deviceChangeLogGetBuildAndUnitIdByRoomId(roomId);
    }

    /**
     * <desc>
     *      获取黑名单信息
     * </desc>
     *
     * @param sn
     * @param page
     * @param pSize
     * @return
     * @author Jiaqi.X
     * @createDate 2019/10/14
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public DeviceBlackListPageVO<BlackListVO> pullBlackList(String sn,String page,String pSize) {
        String deviceUnique = StringHandlerUtil.getElevatorDeviceUniqueBySn(sn);
        DeviceBlackListPageVO<BlackListVO> pager = new DeviceBlackListPageVO<>();
        int currentPage = StringUtils.isNotBlank(page) ? Integer.valueOf(page) : 1;
        int pageSize = StringUtils.isNotBlank(pSize) ? Integer.valueOf(pSize) : 20;
        int startPage = (currentPage-1)*pageSize;
        int endPage = (currentPage-1)*pageSize+pageSize;
        int count = 1;
        int haveNext = 0;
        int currentCount = 0;
        List<String> unitIds = iCloudElevatorDao.getUnitIdsByDeviceUnique(deviceUnique);
        //查询项目的预警次数
        Integer warningTimes = iCloudElevatorDao.getWarningTimesByProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
        List<BlackListVO> blackList = new ArrayList<>();
        Set<String> userIds = new HashSet<>();
        if(unitIds != null && !unitIds.isEmpty()) {
            //地址黑名单
            List<UserBlackInfoVO> users = iCloudElevatorDao.getBlackUserInfos(unitIds,StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
            for (UserBlackInfoVO user : users) {
                if (count >= startPage && count <= endPage) {
                    if(userIds.add(user.getUid()+user.getRoomNo())) {
                        if (user.getUsableCount() == null || user.getUsableCount() <= 0 || (
                                user.getUsableCount() != null && warningTimes != null && user.getUsableCount() <= warningTimes)) {
                            BlackListVO blackListVO = new BlackListVO();
                            blackListVO.setUid(StringHandlerUtil.autlSupply(8, user.getUid(),"0"));
                            if((user.getUsableCount() != null && warningTimes != null && user.getUsableCount()>0 && user.getUsableCount() <= warningTimes)){
                                blackListVO.setStatus(2);
                            }else{
                                blackListVO.setStatus(1);
                            }
                            blackListVO.setType(1);
                            blackListVO.setBatch(Integer.valueOf(user.getBatch()));
                            blackListVO.setRoomNo(StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(user.getRoomNo())), "0").toUpperCase());
                            blackList.add(blackListVO);
                            currentCount++;
                            count++;
                        }
                    }
                } else {
                    haveNext = 1;
                }
            }
            //获取卡黑名单
            List<UserBlackInfoVO> cardInfos = iCloudElevatorDao.getBlackCardInfos(unitIds,StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
            for(UserBlackInfoVO cardInfo : cardInfos){
                if (count >= startPage && count <= endPage) {
                    if (cardInfo.getUsableCount() == null || cardInfo.getUsableCount() <= 0 ||
                        (cardInfo.getUsableCount() != null && warningTimes != null && cardInfo.getUsableCount() <= warningTimes)) {
                        BlackListVO blackListVO = new BlackListVO();
                        blackListVO.setUid(cardInfo.getSoftCardNums());
                        if((cardInfo.getUsableCount() != null && warningTimes != null && cardInfo.getUsableCount()>0 && cardInfo.getUsableCount() <= warningTimes)){
                            blackListVO.setStatus(2);
                        }else{
                            blackListVO.setStatus(1);
                        }
                        blackListVO.setType(2);
                        blackListVO.setBatch(0);
                        blackListVO.setRoomNo(cardInfo.getRoomId());
                        blackList.add(blackListVO);
                        currentCount++;
                        count++;
                    }
                } else {
                    haveNext = 1;
                }
            }
        }

        //临时权限黑名单
        List<UserBlackInfoVO> tempUsers = iCloudElevatorDao.getTempBlackInfos(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique),
                Integer.valueOf(StringHandlerUtil.getDeviceIdByDeviceUnique(deviceUnique)));
        for(UserBlackInfoVO user : tempUsers){
            if(count>=startPage && count<=endPage) {
                if(userIds.add(user.getUid()+user.getRoomNo())) {
                    if (user.getUsableCount() == null || user.getUsableCount() <= 0 || (
                            user.getUsableCount() != null && warningTimes != null && user.getUsableCount() <= warningTimes)) {
                        BlackListVO blackListVO = new BlackListVO();
                        blackListVO.setUid(StringHandlerUtil.autlSupply(8, user.getUid(), "0"));
                        blackListVO.setType(1);
                        if((user.getUsableCount() != null && warningTimes != null && user.getUsableCount()>0 && user.getUsableCount() <= warningTimes)){
                            blackListVO.setStatus(2);
                        }else{
                            blackListVO.setStatus(1);
                        }
                        blackListVO.setBatch(Integer.valueOf(user.getBatch()));
                        blackListVO.setRoomNo(StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(user.getRoomNo())), "0").toUpperCase());
                        blackList.add(blackListVO);
                        currentCount++;
                        count++;
                    }
                }
            }else{
                haveNext = 1;
            }
        }
        pager.setBlackListArr(blackList);
        pager.setTotal(count);
        pager.setPage(currentPage);
        pager.setCurrentTotal(currentCount);
        pager.setHaveNext(haveNext);
        return pager;
    }

    /**
     * <desc>
     *      获取云电梯临时权限
     * </desc>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2019/09/11
     */
    public DeviceAuthTempPageVO<ElevatorTempAuthVO> getTempAuths(String sn,String cPage,String pSize) throws Exception{
        String deviceUnique = StringHandlerUtil.getElevatorDeviceUniqueBySn(sn);
        //获取云电梯临时权限
        DeviceAuthTempPageVO<ElevatorTempAuthVO> page = new DeviceAuthTempPageVO<>();
        int currentPage = StringUtils.isNotBlank(cPage) ? Integer.valueOf(cPage) : 1;
        int pageSize = StringUtils.isNotBlank(pSize) ? Integer.valueOf(pSize) : 20;
        int startPage = (currentPage-1)*pageSize;
        int endPage = (currentPage-1)*pageSize+pageSize;
        int count = 1;
        int haveNext = 0;
        //获取云电梯
        List<Map<String,Object>> auths = iCloudElevatorDao.getTempAuths(Integer.valueOf(StringHandlerUtil.getDeviceIdByDeviceUnique(deviceUnique)),
                StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
        List<ElevatorTempAuthVO> vos = new ArrayList<>();
        for(Map<String,Object> auth : auths) {
            if(count >= startPage && count<=endPage) {
                ElevatorTempAuthVO tempVO = new ElevatorTempAuthVO();
                tempVO.setUserId(StringHandlerUtil.getNullOrStringForObject(auth.get("userId")));
                tempVO.setUserName(StringHandlerUtil.getNullOrStringForObject(auth.get("userName")));
                tempVO.setIdcardKey(StringHandlerUtil.getNullOrStringForObject(auth.get("idcardKey")));
                tempVO.setVisitorType(auth.get("visitorType") != null ? Integer.valueOf(auth.get("visitorType").toString()) : null);
                tempVO.setIsLoss(StringHandlerUtil.getNullOrStringForObject(auth.get("isLoss")));
                //获取电梯的授权设备信息
                List<AppElevatorAuthDTO> elevatorAuths = iCloudElevatorDao.getTempFloorAuth(auth.get("userId").toString(),
                        StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique), Integer.valueOf(StringHandlerUtil.getDeviceIdByDeviceUnique(deviceUnique)));
                AppElevatorAuthVO tempElevatorAuth = StringHandlerUtil.convertElevatorAuth(elevatorAuths);
                Optional<AppElevatorInfoVO> eAuth = tempElevatorAuth.getElevatorAuth().stream().filter(temp -> temp.getDeviceId().equals(StringHandlerUtil.getDeviceIdByDeviceUnique(deviceUnique))).findFirst();
                if (eAuth.isPresent()&&StringUtils.isNotBlank(eAuth.get().getLiveFloor())) {
                    tempVO.setFloor(iCloudElevatorDao.getLogicFloorByNaturalFloor(StringHandlerUtil.splitString(eAuth.get().getLiveFloor()), deviceUnique));
                    vos.add(tempVO);
                    count++;
                }
            }else{
                haveNext = 1;
            }
        }
        //获取访客
        List<DeviceTempVisitorVO> visitors = iDeviceEntranceInfoDao.getVisitors(deviceUnique);
        for(DeviceTempVisitorVO visitor : visitors){
            if(count>=startPage && count<=endPage) {
                ElevatorTempAuthVO tempVO = new ElevatorTempAuthVO();
                BeanUtils.copyProperties(visitor, tempVO);
                if (StringUtils.isNotBlank(visitor.getFrontElevatorAuth())) {
                    Map<String, Object> frontList = JsonUtil.toObject(visitor.getFrontElevatorAuth(), HashMap.class);
                    Set<String> fronts = new HashSet<>();
                    for (String key : frontList.keySet()) {
                        if (key.equals(StringHandlerUtil.getDeviceIdByDeviceUnique(deviceUnique))) {
                            String[] floor = StringHandlerUtil.splitString(frontList.get(key).toString());
                            for (String f : floor) {
                                fronts.add(f);
                            }
                        }
                    }
                    if(!fronts.isEmpty()) {
                        tempVO.setFloor(String.join(",", fronts));
                        tempVO.setFloor(iCloudElevatorDao.getLogicFloorByNaturalFloor(StringHandlerUtil.splitString(tempVO.getFloor()), deviceUnique));
                    }
                }
                if (StringUtils.isNotBlank(visitor.getBackElevatorAuth())) {
                    Map<String, Object> backList = JsonUtil.toObject(visitor.getBackElevatorAuth(), HashMap.class);
                    Set<String> backs = new HashSet<>();
                    for (String key : backList.keySet()) {
                        if (key.equals(StringHandlerUtil.getDeviceIdByDeviceUnique(deviceUnique))) {
                            String[] floor = StringHandlerUtil.splitString(backList.get(key).toString());
                            for (String f : floor) {
                                backs.add(f);
                            }
                        }
                    }
                    if(!backs.isEmpty()) {
                        tempVO.setFloor(String.join(",", backs));
                        tempVO.setFloor(iCloudElevatorDao.getLogicFloorByNaturalFloor(StringHandlerUtil.splitString(tempVO.getFloor()), deviceUnique));
                    }
                }
                vos.add(tempVO);
            }else{
                haveNext=1;
            }
            count++;
        }
        page.setDeviceAuthArr(vos);
        page.setTotal(count);
        page.setPage(currentPage);
        page.setCurrentTotal(pageSize);
        if(null == vos ||  vos.size() <= 0){
            page.setHaveNext(0);
        } else {
            page.setHaveNext(haveNext);
        }
        return page;
    }

    /**
     * <desc>
     *      校验用户信息（目前获取用户或卡号所在房间的通行所剩次数）
     * </desc>
     *
     * @param dto 校验用户信息dto类
     * @return
     * @author Juguang.S
     * @createDate 2020/12/25
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Integer checkUserInfo( CloudDeviceCheckUserInfoDTO dto) throws Exception{
        //查询二维码用户所在房间的剩余次数
        String projectId = StringHandlerUtil.getProjectIdBySn(dto.getSn());
        String uid = dto.getUserInfo().getUserId();
        if(dto.getUserInfo().getType()!=null && dto.getUserInfo().getType()==1){
            String roomNo = dto.getUserInfo().getRoomNo();
            QrcodePassUserInfoVO vo = iPropertyEquipDao.findOwnerQrcodeInfo(uid, projectId, Integer.parseInt(roomNo, 16));
            if(vo != null){
                return vo.getUsableCount();
            }
        }
        //查询刷卡用户所在房间的剩余次数
        if(dto.getUserInfo().getType()!=null && dto.getUserInfo().getType()==2){
            //根据卡号查询卡号所对应的房间及次数信息
            CloudElevatorCardPassInfoVO vo = iCloudElevatorDao.getRoomInfoByCardId(projectId,uid);
            if(vo != null){
                return vo.getUsableCount();
            }
        }
        return null;
    }

    /**
     * <desc>
     *      上报告警信息
     * </desc>
     *
     * @param deviceUnique 设备唯一码
     * @param alarms 告警信息
     * @author Juguang.S
     * @createDate 2021/05/28
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void pushAlarmEvent(String deviceUnique,List<CloudElevatorAlarmInfoDTO> alarms) throws Exception{
        //保存告警信息
        List<Map<String, Object>> alarmList = new ArrayList<>();
        List<Map<String, Object>> alarmListByUpdate = new ArrayList<>();
        for(CloudElevatorAlarmInfoDTO alarmInfoDTO : alarms){
            DeviceAlarmMessageInfoPO alarmMessageInfoPO = new DeviceAlarmMessageInfoPO();
            DeviceAlarmMessageInfoPO alarmMessageInfoPOByUpdate = new DeviceAlarmMessageInfoPO();
            if(StringUtils.isBlank(alarmInfoDTO.getEventSeq())){
                //非通过物业触发的实时抓拍事件 则进行保存告警信息
                alarmMessageInfoPO.setAlarmId(LogicIdUtil.bussinessId());
                alarmMessageInfoPO.setElevatorDeviceUnique(deviceUnique);
                alarmMessageInfoPO.setAlarmType(alarmInfoDTO.getType());
                alarmMessageInfoPO.setAlarmTime(DateUtil.formatStringToDate(alarmInfoDTO.getEventTime(), DateUtil.DATE_FORMAT_TYPE1));
                alarmMessageInfoPO.setProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
                alarmMessageInfoPO.setCreateTime(new Date());
                alarmMessageInfoPO.setUpdateTime(new Date());
                //上传图片
                if(StringUtils.isNotBlank(alarmInfoDTO.getImage())){
                    InputStream input = new ByteArrayInputStream(StringHandlerUtil.imageBase64StrToByte(alarmInfoDTO.getImage()));
                    alarmMessageInfoPO.setAlarmPhotoUrl(this.uploadFile(input,"png"));
                }
                alarmList.add(SqlUtil.durableData(alarmMessageInfoPO,PlatformConstants.TABLE_SAVE));
            }else{
                alarmMessageInfoPOByUpdate.setAlarmId(alarmInfoDTO.getEventSeq());
                alarmMessageInfoPOByUpdate.setClickMark(1);
                //上传图片
                if(StringUtils.isNotBlank(alarmInfoDTO.getImage())){
                    InputStream input = new ByteArrayInputStream(StringHandlerUtil.imageBase64StrToByte(alarmInfoDTO.getImage()));
                    alarmMessageInfoPOByUpdate.setCandidPhotoUrl(this.uploadFile(input,"png"));
                }else{
                    continue;
                }
                alarmMessageInfoPOByUpdate.setUpdateTime(new Date());
                alarmListByUpdate.add(SqlUtil.durableData(alarmMessageInfoPOByUpdate,PlatformConstants.TABLE_UPDATE));
            }
        }
        if(alarmList!=null && alarmList.size()>0){
            iCloudElevatorDao.batchSave(alarmList);
        }
        if(alarmListByUpdate!=null && alarmListByUpdate.size()>0){
            iCloudElevatorDao.batchUpdate(alarmListByUpdate);
        }
    }

    /**
     * <desc>
     *      查询云电梯所绑定的摄像头相关参数配置
     * </desc>
     *
     * @param cloudElevatorVO
     * @return
     * @author Juguang.S
     * @createDate 2021/05/31
     */
    public DeviceAiCameraInfoVO getAiCameraInfoByElevatorDeviceUnique(CloudElevatorVO cloudElevatorVO) throws Exception{
        return iCloudElevatorDao.getAiCameraInfoByElevatorDeviceUnique(cloudElevatorVO.getDeviceUnique());
    }

    /**
     * <desc>
     *      Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @param fileType 文件类型
     * @return 文件上传成功后会返回Url,否则返回空
     * @author Qiang.S
     * @createDate 2019/02/22
     */
    private String uploadFile(InputStream inputStream, String fileType) throws IOException {
        String fileUrl = "";
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                fileType,
                FILE_ACCESS_URL,
                FileCatalogEnum.DEVICE_ALARM_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean)resultMap.get("returnCode");
        if (returnCode == false){
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }
}
